package com.ncloud.crm.utils;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.ContextLoader;


/**
 * @Author:LZY
 * @Date:2015/2/21
 * @Function:工具类。
 * */
public class Utility {
	private static Utility utility = null;
	private Utility(){
		
	}
	public static Utility getInstance(){
		if(utility == null){
			utility = new Utility();
		}
		return utility;
	}

	/**
	 * @Author:LZY 
	 * @Date:2015/2/8 
	 * @Function：获取SpringBean根据类名
	 * @2015/2/28
	 * @desc Fixed a Exception 服务启动的时候可能还没做完context，就被调用
	 * @throws ClassNotFoundException 
	 * @throws BeansException 
	 * */
	public static Object getBean(String beanName) throws BeansException, ClassNotFoundException  {
		ApplicationContext ac = ContextLoader.getCurrentWebApplicationContext();
		return ac == null ? null : ac.getBean(Class.forName(beanName));
	}

	/**
	 * @Author:LZY 
	 * @Date:2015/2/8 
	 * @Function：获取SpringBean根据Class
	 * @2015/2/28
	 * Fixed a Exception 服务启动的时候可能还没做完context，就被调用
	 * @return 
	 * */
	public static <T> T getBean(Class<T> clasz)  {
		ApplicationContext ac = ContextLoader.getCurrentWebApplicationContext();
		return ac == null ? null : ac.getBean(clasz);
	}

	/**
	 * @Author:LZY 
	 * @Date:2015/3/6 
	 * @Function：获取异常信息
	 * */
	public static String getExceptionStack(Exception e) {
		ByteArrayOutputStream buf = new ByteArrayOutputStream();
		e.printStackTrace(new PrintWriter(buf, true));
		return buf.toString();
	}
	/**
	 * @Author:LZY 
	 * @Date:2015/3/6 
	 * @Fuction:根据地址获取InputStream
	 * */
	public static InputStream getClassResourceStream(String file)  {
		InputStream in = new Utility().getClass().getClassLoader()
				.getResourceAsStream(file);
		if (in == null)
			throw new RuntimeException("file " + file + " not exist!");
		return in;
	}
	/**
	 * @Author:LZY 
	 * @Date:2015/3/6 
	 * @Fuction:根据地址获取URL
	 * */
	public static URL getClassResource(String file)  {
		URL url = new Utility().getClass().getClassLoader().getResource(file);
		if (url == null)
			throw new RuntimeException("file " + file + " not exist!");
		return url;
	}


	/**
	 * @Author:LZY 
	 * @Date:2015/2/26 
	 * @Fuction:将String写入outputStream
	 * */
	public static void copyBytes(String string,OutputStream os,String...charSets) throws IOException {
		String charset = null;
		charset = charSets != null && charSets.length > 0 ? charSets[0] : "UTF-8";
		byte[] b = string.getBytes(charset);
		os.write(b);
	}
	/**
	 * @Author:LZY 
	 * @Date:2015/2/26 
	 * @Fuction:将InputStream写入String
	 * */	
	public static String stream2String(InputStream stream,String...charSets) throws UnsupportedEncodingException, IOException {
		String charset = null;
		charset = charSets != null && charSets.length > 0 ? charSets[0] : "UTF-8";
		BufferedInputStream bs = new BufferedInputStream(stream);
		byte[] b = new byte[1024];
		StringBuffer buffer = new StringBuffer();
		int readCount = 0;
		while ((readCount = bs.read(b)) != -1) {
			buffer.append(new String(b,0,readCount,charset));
		}
		return buffer.toString();
	}
	/**
	 * @Author:LZY 
	 * @Date:2015/2/26 
	 * @Fuction:读取File写入String
	 * */
	public static String file2String(File file) throws IOException {
		StringBuffer buffer = new StringBuffer();
		FileReader reader = new FileReader(file);
		@SuppressWarnings("resource")
		BufferedReader br = new BufferedReader(reader);
		String line = null;
		while((line = br.readLine()) != null)
			buffer.append(line);
		return buffer.toString();
	}
	/**
	 * @Author:LZY 
	 * @Date:2015/2/26 
	 * @Fuction:读取File写入String
	 * */
	public static String file2String(String fileName) throws IOException {
		File file = new File(fileName);
		return file2String(file);
	}
	/**
	 * @Author:LZY 
	 * @Date:2015/2/28 
	 * @Fuction:FormatDate
	 * */
	public static String dateToStr(Date date, String pattern) {
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		return sdf.format(date);
	}

	/**
	 * @Author:LZY 
	 * @Date:2015/3/5 
	 * @Fuction:获取异常原始触发信息，如果想要链中所有异常信息，用这个。
	 * */
	public static List<String> getErrMsg(Exception e){
		List<String> errors = new ArrayList<>();
		dealWithCause(e, errors);
		return errors;
	}
	private static void dealWithCause(Throwable throwable,List<String> errors){
		Throwable inner = throwable.getCause();
		if(inner != null){
			String msg = inner.getMessage();
			errors.add(msg);
			dealWithCause(inner, errors);
		}
	}
	public static Integer getAcceptMonth(String dateStr,String parsePatterns) throws ParseException{
		if(parsePatterns == null) parsePatterns = "yyyyMMddHHmmss";
		Date date = DateUtils.parseDate(dateStr, parsePatterns);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return new Integer(calendar.get(Calendar.MONTH) + 1);
	}
	public static Integer getAcceptMonth(String order_id){
		String month = order_id.substring(4, 6);
		return Integer.parseInt(month);
	}
	public static boolean isNullEmpty(String str){
		 if(str == null || str.isEmpty()){
			 return true;  
		 }else{
			 return false;
		 }
	}
	public static Date Str2Date(String dateStr,String format) throws ParseException{
		format = format == null ? "yyyyMMddHHmmss": format;
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.parse(dateStr);
	}
	/**
	 * mode=1,当前日期的零分零秒
	 * mode=2,当月月初
	 * mode=3,当月月末
	 * mode=4,上月月初
	 * mode=5,上月月末
	 * mode=6,次月月初
	 * mode=7,次月月末
	 * mode=0,偏移
	 * */
	public static String getTargetDate(String dateStr,Integer mode,Integer field,Integer amount,String format) throws ParseException{
		return getTargetDate(Str2Date(dateStr,format), mode, field, amount, format);
	}
	public static String getTargetDate(Date date,Integer mode,Integer field,Integer amount,String format){
		String result = null;
		format = format == null ? "yyyyMMddHHmmss": format;
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		Calendar instance = Calendar.getInstance();
		switch(mode){
		case 1: 
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),calendar.get(Calendar.DATE),0,0,0);
			result = sdf.format(instance.getTime());
			break;
		case 2:
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),1,0,0,0);
			result = sdf.format(instance.getTime());
			break;
		case 3:
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH) + 1,1,0,0,0);
			instance.add(Calendar.SECOND, -1);
			result = sdf.format(instance.getTime());
			break;
		case 4:
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH) - 1,1,0,0,0);
			result = sdf.format(instance.getTime());
			break;
		case 5:
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),1,0,0,0);
			instance.add(Calendar.SECOND, -1);
			result = sdf.format(instance.getTime());
			break;	
		case 6:
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH) + 1,1,0,0,0);
			result = sdf.format(instance.getTime());
			break;
		case 7:
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH) + 2,1,0,0,0);
			instance.add(Calendar.SECOND, -1);
			result = sdf.format(instance.getTime());
			break;
		case 8:
			calendar.add(field, amount);
			result = sdf.format(calendar.getTime());
			break;
		}
		return result;
	}
	public static String getTargetDate(String dateStr,Integer mode,String format) throws ParseException{
		return getTargetDate(Str2Date(dateStr,format), mode, format);
	}
	public static String formatDateStr(String dateStr,String format,String target) throws ParseException{
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		target = target == null || "".equals(target) ? "yyyyMMddHHmmss":target;
		return new SimpleDateFormat(target).format(sdf.parse(dateStr));
	}
	public static String getTargetDate(Date date,Integer mode,String format){
		String result = null;
		format = format == null ? "yyyyMMddHHmmss": format;
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		Calendar instance = Calendar.getInstance();
		switch(mode){
		case 1: 
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),calendar.get(Calendar.DATE),0,0,0);
			result = sdf.format(instance.getTime());
			break;
		case 2:
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),1,0,0,0);
			result = sdf.format(instance.getTime());
			break;
		case 3:
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH) + 1,1,0,0,0);
			instance.add(Calendar.SECOND, -1);
			result = sdf.format(instance.getTime());
			break;
		case 4:
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH) - 1,1,0,0,0);
			result = sdf.format(instance.getTime());
			break;
		case 5:
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),1,0,0,0);
			instance.add(Calendar.SECOND, -1);
			result = sdf.format(instance.getTime());
			break;	
		case 6:
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH) + 1,1,0,0,0);
			result = sdf.format(instance.getTime());
			break;
		case 7:
			instance.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH) + 2,1,0,0,0);
			instance.add(Calendar.SECOND, -1);
			result = sdf.format(instance.getTime());
			break;
		}
		return result;
	}

	// 1 > 2 true
	public static boolean compareDate(String s1,String s2) throws ParseException{
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		return sdf.parse(s1).getTime() > sdf.parse(s2).getTime();
	}
	
	public static String getRandomString(int length) { //length表示生成字符串的长度  
	    String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";     
	    Random random = new Random();     
	    StringBuffer sb = new StringBuffer();     
	    for (int i = 0; i < length; i++) {     
	        int number = random.nextInt(base.length());     
	        sb.append(base.charAt(number));     
	    }     
	    return sb.toString();     
	 }
}